// 1.接口（函数必传）
function interface_fun(labelObj: { name: string }) {
  console.log(labelObj);
}
interface_fun({ name: "xdj" }); //参数对象的name必传且为string

//接口写法

function interface_fun1(labelObj: labelObj_face) {
  console.log(labelObj);
}
interface_fun1({ old: 22, name: "xdj" });
interface labelObj_face {
  old: number;
  name: string;
} //可以提前

//2.可选属性
interface interface_option {
  name: string;
  old?: number;
}
function fun_option(obj: interface_option) {
  console.log(obj);
}
fun_option({name:'xdj'})
fun_option({old:2,name:'x'})

//3.只读属性
interface redayOnly{
    name:string
   readonly old:number
}
let redayOnlyObj:redayOnly={
    name:'xdj',
    old:2
}
// redayOnlyObj.old=2 //error
let arr :ReadonlyArray<number> = [1,2,3,4]
// arr[2] =3 error


// 4.额外的属性检查
interface SquareConfig {
    color?: string;
    width?: number;
}
function createSquare(config: SquareConfig) {
    console.log(config);
}
//show属性没有接口认定（报错：存在未认定目标类型的属性）
//方法一：as类型断定绕开这些检查
createSquare({ show: "red", width: 100 } as SquareConfig);
//方法二：
interface SquareConfig {
    color?: string;
    width?: number;
    [propName: string]: any;
}
//方法三：对象赋值给一个另一个变量： 因为 squareOptions不会经过额外属性检查，所以编译器不会报错
let squareOptions = { colour: "red", width: 100 };
let mySquare = createSquare(squareOptions);


// 5.函数类型(接口由参数值和返回值组成)
interface SearchFunc{
    (name:string,old:number):boolean
}
let mySearch: SearchFunc;
mySearch = function(src, sub) {
   console.log(src,sub);
   return false
}

// 6.可索引的类型

